package com.example.aop;

import com.example.annotation.BlakList;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

/**
 * @Author 游家纨绔
 * @Description TODO
 * @Create 2023-09-10 19:30
 */
@Aspect
@Component
public class SecKillAop {

	@Autowired
	private RedisTemplate<String, Object> redisTemplate;

	@Around(value = "execution(* *..SecKillController.secKillGoods(..))")
	public Object secKill(ProceedingJoinPoint pjp) {
		MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
		Method method = methodSignature.getMethod();
		try {
			if (method.isAnnotationPresent(BlakList.class)) {
				// 获取注解参数
				int limit = method.getAnnotation(BlakList.class).limit();
				Object[] args = pjp.getArgs();
				Map<String, Map<String, Object>> arg = (Map<String, Map<String, Object>>) args[0];
				Integer userId = (Integer) arg.get("user").get("id");
				Integer skuId = (Integer) arg.get("sku").get("id");
				if (redisTemplate.hasKey(userId + "-" + skuId)) {
					Integer count = (Integer) redisTemplate.opsForValue().get(userId + "-" + skuId);
					if (count < limit) {
						redisTemplate.opsForValue().increment(userId + "-" + skuId);
					} else {
						arg.get("user").put("id", 0);
						return pjp.proceed(args);
					}
				}
				redisTemplate.opsForValue().set(userId + "-" + skuId, 1, 5, TimeUnit.SECONDS);
			}

			return pjp.proceed();
		} catch (Throwable e) {
			throw new RuntimeException(e);
		}
	}

}
